/**
 * 科大讯飞语音识别封装 - 微信小程序版本
 */
export class SpeechRecognizer {
  constructor(options) {
    this.options = options || {}
    this.recorderManager = uni.getRecorderManager()
    this.audioContext = null
    this.isRecording = false
    this.audioFilePath = ''
    
    // 事件监听
    this.recorderManager.onStart(() => {
      this.notifyStatus('开始录音')
      this.isRecording = true
    })
    
    this.recorderManager.onStop((res) => {
      this.isRecording = false
      this.audioFilePath = res.tempFilePath
      this.notifyStatus('录音完成', '正在上传识别...')
      this.recognizeAudio()
    })
    
    this.recorderManager.onError((err) => {
      this.isRecording = false
      this.notifyError(err)
    })
  }
  
  // 开始录音
  start() {
    return new Promise((resolve, reject) => {
      if (this.isRecording) {
        reject(new Error('正在录音中'))
        return
      }
      
      const options = {
        format: 'mp3',
        sampleRate: 16000,
        numberOfChannels: 1,
        encodeBitRate: 48000
      }
      
      this.recorderManager.start(options)
      setTimeout(() => {
        resolve()
      }, 300) // 给录音启动一些时间
    })
  }
  
  // 停止录音
  stop() {
    if (this.isRecording) {
      this.recorderManager.stop()
    }
  }
  
  // 识别音频
  recognizeAudio() {
    if (!this.audioFilePath) {
      this.notifyError(new Error('没有录音文件'))
      return
    }
    
    // 读取音频文件并转换为Base64
    uni.getFileSystemManager().readFile({
      filePath: this.audioFilePath,
      encoding: 'base64',
      success: (res) => {
        const base64Audio = res.data
        this.sendAudioToIflytek(base64Audio)
      },
      fail: (err) => {
        this.notifyError(new Error('读取录音文件失败'))
      }
    })
  }
  
  // 发送音频到科大讯飞API
  sendAudioToIflytek(base64Audio) {
    const { appId, apiKey } = this.options
    
    if (!appId || !apiKey) {
      this.notifyError(new Error('缺少科大讯飞API凭证'))
      return
    }
    
    // 构建请求参数
    const params = {
      appId: appId,
      format: 'mp3',
      sampleRate: 16000,
      audio: base64Audio,
      engineType: 'sms16k', // 中文普通话
      timeout: 30000
    }
    
    // 生成签名
    const xAppid = appId
    const xCurTime = Math.floor(Date.now() / 1000).toString()
    const xParam = this.base64Encode(JSON.stringify({
      engine_type: params.engineType,
      aue: 'raw'
    }))
    const xCheckSum = this.generateCheckSum(apiKey, xCurTime, xParam)
    
    // 发送请求
    uni.request({
      url: 'https://api.xfyun.cn/v1/service/v1/iat',
      method: 'POST',
      header: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
        'X-Appid': xAppid,
        'X-CurTime': xCurTime,
        'X-Param': xParam,
        'X-CheckSum': xCheckSum
      },
      data: {
        audio: params.audio
      },
      success: (response) => {
        if (response.statusCode === 200 && response.data) {
          try {
            const result = JSON.parse(response.data)
            if (result.code === '0') {
              const text = result.data.result.ws.map(item => 
                item.cw.map(word => word.w).join('')
              ).join('')
              this.notifyResult(text)
            } else {
              this.notifyError(new Error(`识别失败: ${result.code} - ${result.message}`))
            }
          } catch (parseError) {
            this.notifyError(new Error('解析识别结果失败'))
          }
        } else {
          this.notifyError(new Error(`API请求失败: ${response.statusCode}`))
        }
      },
      fail: (err) => {
        this.notifyError(new Error(`网络错误: ${err.errMsg}`))
      }
    })
  }
  
  // 翻译文本
  translate(text, from = 'zh', to = 'en') {
    return new Promise((resolve, reject) => {
      const { appId, apiKey } = this.options
      
      if (!appId || !apiKey) {
        reject(new Error('缺少科大讯飞API凭证'))
        return
      }
      
      // 构建请求参数
      const salt = Date.now()
      const params = {
        q: text,
        from: from,
        to: to,
        appid: appId,
        salt: salt,
        sign: this.generateSign(appId, text, salt, apiKey)
      }
      
      // 发送请求
      uni.request({
        url: 'https://openapi.iflytek.com/api/v1/translation',
        method: 'POST',
        header: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        data: params,
        success: (response) => {
          if (response.statusCode === 200 && response.data) {
            try {
              const result = response.data
              if (result.code === 0 && result.data && result.data.trans_result) {
                const translatedText = result.data.trans_result[0].dst
                resolve(translatedText)
              } else {
                reject(new Error(`翻译失败: ${result.code} - ${result.message}`))
              }
            } catch (parseError) {
              reject(new Error('解析翻译结果失败'))
            }
          } else {
            reject(new Error(`API请求失败: ${response.statusCode}`))
          }
        },
        fail: (err) => {
          reject(new Error(`网络错误: ${err.errMsg}`))
        }
      })
    })
  }
  
  // 生成签名
  generateSign(appId, text, salt, apiKey) {
    // 使用微信小程序的加密API
    return this.md5(`${appId}${text}${salt}${apiKey}`)
  }
  
  // 生成语音识别API的CheckSum
  generateCheckSum(apiKey, curTime, param) {
    // 使用微信小程序的加密API
    return this.sha1(`${apiKey}${curTime}${param}`)
  }
  
  // Base64编码
  base64Encode(str) {
    // 微信小程序中可以使用原生的Base64编码
    return btoa(unescape(encodeURIComponent(str)))
  }
  
  // MD5实现
  md5(str) {
    // 微信小程序中可以使用crypto-js或其他加密库
    // 这里使用简化版实现，实际项目中请替换为真正的MD5库
    return str // 实际项目中应使用加密库
  }
  
  // SHA-1实现
  sha1(str) {
    // 微信小程序中可以使用crypto-js或其他加密库
    // 这里使用简化版实现，实际项目中请替换为真正的SHA-1库
    return str // 实际项目中应使用加密库
  }
  
  // 通知结果
  notifyResult(result) {
    if (typeof this.options.onRecognize === 'function') {
      this.options.onRecognize(result)
    }
  }
  
  // 通知错误
  notifyError(error) {
    if (typeof this.options.onError === 'function') {
      this.options.onError(error)
    }
  }
  
  // 通知状态变化
  notifyStatus(status, detail = '') {
    if (typeof this.options.onStatusChange === 'function') {
      this.options.onStatusChange(status, detail)
    }
  }
  
  // 销毁资源
  destroy() {
    if (this.isRecording) {
      this.recorderManager.stop()
    }
    this.recorderManager = null
    this.audioContext = null
  }
}
    